package book;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 用ReentrantLock实现的生产者消费者模式
 * @author：涂有
 * @date 2017年2月28日 下午11:22:10
 */
public class ReentrantLockProducerConsumerTest{

	private Lock lock = new ReentrantLock();
	private Condition condition = lock.newCondition();
	private boolean goods = false;
	
	public void produce(){
		
		lock.lock();
		try{
			while(goods){
				
				try {
					condition.await();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			System.out.println("生产》》》");
			condition.signal();
			goods = true;
		}finally{
			lock.unlock();
		}
	}
	
	public void consume(){
		
		lock.lock();
		try{
			while(!goods){
				
				try {
					condition.await();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			System.out.println("消费《《《");
			condition.signal();
			goods = false;
		}finally{
			lock.unlock();
		}
	}
	
	static class ThreadP implements Runnable{
		
		ReentrantLockProducerConsumerTest obj;
		
		public ThreadP(ReentrantLockProducerConsumerTest obj){
			
			this.obj = obj;
		}
		
		@Override
		public void run() {

			while(true){
				
				obj.produce();
			}
		}
	}
	
	static class ThreadC implements Runnable{
		
		ReentrantLockProducerConsumerTest obj;
		
		public ThreadC(ReentrantLockProducerConsumerTest obj){
			
			this.obj = obj;
		}
		
		@Override
		public void run() {
			
			while(true){
				
				obj.consume();
			}
		}
	}
	
	public static void main(String[] args) {
		
		ReentrantLockProducerConsumerTest lockTask = new ReentrantLockProducerConsumerTest();
		Thread tp = new Thread(new ThreadP(lockTask));
		Thread tc = new Thread(new ThreadC(lockTask));
		tp.start();
		tc.start();
	}
}
